package net.alpcontrol.bi;

import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName: MpGenerator
 * @Description: 代码生成器
 * @author congqing
 * @date 2019-11-14
 */
public class CodeGenerator {

    /** 配置文件修改后不要提交git,防止影响其他开发成员 **/
    /** 代码生成【第一次使用请配置initParam↓中的信息，每次生成时填写表及包相关信息】**/
    public static void main(String[] args) {
        //要去掉的表前缀
        String tablePrefix = "";
        //要生成代码的包路径
        String packageName = "net.alpcontrol.bi.colligation";
        //要生成的表集合
        String[] tables = new String[]{"pj_project_building"};

        //生成
        CodeGenerator.getInstance().generateByTables(tablePrefix, packageName, tables);
    }

    /** 配置信息【生成规则配置信息，请确保配置正确】**/
    private void initParam(){
        //作者
        this.author = "丛庆";
        //文件输出路径,可手动修改指定
        this.outputDir = FileUtil.getWebRoot() + "/src/main/java/";
        //mapper.xml输出路径
        this.outputDirXml = FileUtil.getWebRoot() + "/src/main/resources/mapper/";
        //数据库类型
        this.dbType = DbType.SQL_SERVER;
        //数据库驱动
        this.dbDriver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
        //数据库用户名
        this.dbUser = "sa";
        //数据库密码
        this.dbPwd = "Alp123455";
        //数据库URL
        this.dbUrl = "jdbc:sqlserver://124.70.20.142:9344;DatabaseName=hanpu_bi;";
        //生成是否覆盖，建议设置为false
        this.fileOverride = true;
        //生成后是否打开目录sendMessage.getMessageId()
        this.fileOpen = true;

    }

    /**生成相关**/
    private String author,outputDir,outputDirXml,dbDriver,dbUser,dbPwd,dbUrl;
    private DbType dbType;
    private boolean fileOverride,fileOpen;
    private static CodeGenerator codeGenerator;

    static {
        codeGenerator = new CodeGenerator();
    }

    private CodeGenerator() {
        this.initParam();
    }

    public static CodeGenerator getInstance(){
        return codeGenerator;
    }

    private void generateByTables(boolean serviceNameStartWithI,String tablePrefix, String packageName, String... tableNames) {
        GlobalConfig config = new GlobalConfig();
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(this.dbType)
                .setUrl(this.dbUrl)
                .setUsername(this.dbUser)
                .setPassword(this.dbPwd)
                .setDriverName(this.dbDriver);
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig
                .setCapitalMode(true)
                .setEntityLombokModel(true)
//                .setDbColumnUnderline(true)
//                .setSuperEntityClass(BaseEntity.class)
//                .setSuperEntityColumns("CREATE_TIME","UPDATE_TIME")
                .setTablePrefix(tablePrefix)
                .setRestControllerStyle(true)
                .setNaming(NamingStrategy.underline_to_camel)
                .setInclude(tableNames);
        config.setActiveRecord(false)
                .setBaseResultMap(true)
                .setBaseColumnList(true)
                .setDateType(DateType.ONLY_DATE)
                .setAuthor(this.author)
                .setOutputDir(this.outputDir)
                .setOpen(this.fileOpen)
                .setSwagger2(false)
                .setFileOverride(this.fileOverride);

        if (!serviceNameStartWithI) {
            config.setServiceName("%sService");
        }

        // 注入自定义配置，可以在 VM 中使用 cfg.abc 【可无】
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                Map<String, Object> map = new HashMap<>();
                map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-rb");
                this.setMap(map);
            }
        };

        //修改mapper.xml生成路径
        List<FileOutConfig> focList = new ArrayList<>();
        // 调整 xml 生成目录演示
        focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return outputDirXml + packageName.replace(".", File.separator) + File.separator + "mapping" + File.separator + tableInfo.getEntityName() + "Mapper.xml";
            }
        });
        cfg.setFileOutConfigList(focList);

        // 自定义模板配置，可以 copy 源码 mybatis-plus/src/main/resources/templates 下面内容修改，
        // 放置自己项目的 src/main/resources/templates 目录下, 默认名称一下可以不配置，也可以自定义模板名称
        TemplateConfig templateConfig = new TemplateConfig();
        templateConfig.setController("/templates/controller.java");
//        templateConfig.setController(null);
        templateConfig.setService("/templates/service.java");
        templateConfig.setServiceImpl("/templates/serviceImpl.java");
        templateConfig.setEntity("/templates/entity.java");
        templateConfig.setMapper("/templates/mapper.java");
        templateConfig.setXml(null);
        // 如上任何一个模块如果设置 空 OR Null 将不生成该模块。

        new AutoGenerator().setTemplateEngine(new FreemarkerTemplateEngine())
                .setTemplate(templateConfig)
                .setGlobalConfig(config)
                .setDataSource(dataSourceConfig)
                .setStrategy(strategyConfig)
                .setCfg(cfg)
                .setPackageInfo(
                        new PackageConfig()
                                .setParent(packageName)
                                .setController("controller")
                                .setEntity("entity")
                ).execute();
    }

    private void generateByTables(String tablePrefix,String packageName, String... tableNames) {
        this.generateByTables(true,tablePrefix, packageName, tableNames);
    }

}
